package com.cat.mrli.rat.util;

import android.opengl.GLES20;
import android.util.Log;

import java.util.logging.Logger;

import static android.opengl.GLES20.*;

/**
 * Created by MrLi on 2017/6/21.
 */

public final class ShaderHelper {
    private static final String TAG = "shaderHelper";

    public static int compileVertexShader(String shaderCode) {
        return compileShader(GL_VERTEX_SHADER, shaderCode);
    }

    public static int compileFragmentShader(String shaderCode) {
        return compileShader(GL_FRAGMENT_SHADER, shaderCode);
    }

    private static int compileShader(int type, String shaderCode) {
        final int shaderObjectID = GLES20.glCreateShader(type);
        if (0 == shaderObjectID) {
            Log.w(TAG, "无法创建着色器");
            return 0;
        }
        glShaderSource(shaderObjectID, shaderCode);
        glCompileShader(shaderObjectID);
        final int[] compileStatus = new int[1];
        glGetShaderiv(shaderObjectID, GL_COMPILE_STATUS, compileStatus, 0);
        if (LoggerConfig.ON) {
            Log.v(TAG, glGetShaderInfoLog(shaderObjectID));
        }
        if (0 == compileStatus[0]) {
            glDeleteShader(shaderObjectID);
            if (LoggerConfig.ON) {
                Log.w(TAG, "生成失败");
            }
            return 0;
        }
        return shaderObjectID;
    }

    public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
        final int programObjectID = glCreateProgram();
        if (0 == programObjectID) {
            Log.w(TAG, "无法创建着色器程序");
            return 0;
        }
        glAttachShader(programObjectID, vertexShaderId);
        glAttachShader(programObjectID, fragmentShaderId);
        glLinkProgram(programObjectID);
        final int[] linkStatus = new int[1];
        glGetProgramiv(programObjectID, GL_LINK_STATUS, linkStatus, 0);
        if (LoggerConfig.ON) {
            Log.w(TAG, "linkStatus" + linkStatus[0]);
        }
        if (0 == linkStatus[0]) {
            glDeleteProgram(programObjectID);
            return 0;
        }
        return programObjectID;
    }


    public static boolean validProgram(int programObjectID) {
        glValidateProgram(programObjectID);
        final int[] validStatus = new int[1];
        glGetProgramiv(programObjectID, GL_VALIDATE_STATUS, validStatus, 0);
        return 0 != validStatus[0];
    }


    public static int buildProgram(String vertexShaderSource,
                                   String fragmentShaderSource) {
        int program;
        int vertexSahder = compileVertexShader(vertexShaderSource);
        int fragmentShader = compileFragmentShader(fragmentShaderSource);

        program = linkProgram(vertexSahder, fragmentShader);
        if (LoggerConfig.ON) {
            validProgram(program);
        }
        return program;
    }

}
